package com.colt.contentcenter.controller.share;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.colt.contentcenter.domain.dto.user.UserDTO;
import com.colt.contentcenter.feighclient.TestBaiduFeighClient;
//import com.colt.contentcenter.rocketmq.MySource;
import com.colt.contentcenter.sentineldemo.TestControllerBlockHandlerClass;
import com.colt.contentcenter.service.share.ShareService;
import com.colt.contentcenter.util.RedisServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.http.*;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

/**
 * @program: content-center
 * @description: 测试Controller
 * @author: colt
 * @create: 2020-05-13 15:01
 **/
@Slf4j
@RequestMapping("/test")
@RestController
//属性动态刷新
@RefreshScope
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TestController {
    private final RedisServiceImpl redisService;
    private  final ShareService shareService;
    private  final TestBaiduFeighClient testBaiduFeighClient;
    private  final RocketMQTemplate rocketMQTemplate;
    private  final RestTemplate restTemplate;
    @GetMapping("/redis")
    public void  testRedis(){
        redisService.set("mastaaa","set????");
    }
    @GetMapping("/redisget")
    public String  testRedisget(){
        return redisService.get("master");
    }
    /*@Value("${your.configuration}")
    private String yourConfiguration;

    @GetMapping("/testConfig")
    public String testConfig(){
        return this.yourConfiguration;
    }*/
    @GetMapping("/test-node-service")
    public String testOtherService(){
        return this.restTemplate.getForObject(
//                此路径可以调用到异构微服务的首页 localhost:8060
                "http://wii",
                String.class);
    }

    @RequestMapping("/test-tokenRelay/{userId}")
    public ResponseEntity<UserDTO> testTokenRelay(@PathVariable("userId") Integer userId, HttpServletRequest request){
        HttpHeaders headers = new HttpHeaders();
        headers.add("X-Token",request.getHeader("X-Token"));
        return this.restTemplate.exchange(
                "http://user-center/users/{id}",
                HttpMethod.GET,//请求方式
                new HttpEntity<>(headers),
                UserDTO.class,
                userId
        );
    }

    @GetMapping("/baidu")
    public String getIndex(){
        return   testBaiduFeighClient.baiduIndex();
    }

    @GetMapping("/test-a")
    public  String  testa(){
        return "test-ssasdasdsaaaaaaaaaaaaaaaaaaaaaasdasdssaa";
    }
    @GetMapping("test-b")
    public  String  testb(){
        return "test-b";
    }
    @GetMapping("test-hot")
    @SentinelResource("hot")
    public  String  testHot(@RequestParam(required = false) String a, @RequestParam(required = false) String b){
        return a+"--"+b;
    }
    @GetMapping("test-sentinel-api")
    public String testSentinelAPI(@RequestParam(required = false) String a ){
        String resourceName = "test-sentinel-api";
        //针对来源
        ContextUtil.enter(resourceName,"test-wfw");
        Entry entry = null;
        try {
            //定义一个sentinel保护的资源 名称为括号内容   需要唯一
            entry = SphU.entry(resourceName);
            //被保护的业务逻辑
            if (StringUtils.isBlank(a)){
                throw new IllegalArgumentException("a不能为空！！！");
            }
            return a;
            //若保护的的资源被限流或者降级，就会抛出BlockException
        } catch (BlockException e) {
            log.warn("资源被降级或者限流了",e);
            return "资源被降级或者限流了";
        }
        //如果需要统计BlockException以外的分支
        catch (IllegalArgumentException e2){
            //统计IllegalArgumentException发生次数
            Tracer.trace(e2);
            return "参数非法";
        }
        finally {
            if (entry!=null){
                //类似于io流的操作
                entry.exit();
                ContextUtil.exit();
            }
        }
    }
    @GetMapping("test-sentinel-resource")
    @SentinelResource(value = "test-sentinel-api",
            blockHandler = "block",
            fallback = "fallBack",
            blockHandlerClass = TestControllerBlockHandlerClass.class)//此注解不支持来源
    public String testSentinelAPIResource(@RequestParam(required = false) String a ){
        //被保护的业务逻辑
        if (StringUtils.isBlank(a)){
            throw new IllegalArgumentException("a can not be null！！！");
        }
        return a;
    }

    /**
     * @Description: 1.5 处理降级
     * sentinel1.6后  可以处理Throwable
     * @Param:
     * @return:
     * @Author: colt
     * @Date: 2020/5/26
     */
    public String fallBack(@RequestParam(required = false) String a ){
        log.warn("资源被降级了");
        return "资源被降级了,fallback";
    }



    @RequestMapping("/test-sentinel-rest-template/{userId}")
    public UserDTO testSentinelRestTemplate(@PathVariable("userId") Integer userId){
        UserDTO userDTO = this.restTemplate.getForObject("http://localhost:8089/users/{id}", UserDTO.class,userId);
        return userDTO;
    }
    @Autowired
    private Source source;
    @GetMapping("/test-stream")
    public String testStream(){
        this.source.output()
                .send(
                        MessageBuilder.withPayload("消息体")
                        .build()
                );
        return "success";
    }
  /*  @Autowired
    private MySource mySource;
    @GetMapping("/test-stream-my-output")
    public String testStreamMyOutPut(){
        this.mySource.outPut()
                .send(
                        MessageBuilder
                                .withPayload("指定消息体")
                                .setHeader("my-header","xixihaha")
                                .build()
                );
        this.mySource.outPut().send(
                MessageBuilder
                        .withPayload(UserDTO.builder().roles("12").build())
                        .setHeader("auto-header","hhhh")
                        .build()
        );
        return "success";
    }*/

}
